/* var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };
console.log(a.x);
console.log(b);  */

/* 
当代前端开发，我们一般会基于 “函数表达式  const xxx=function(){}” 来声明定义一个函数：
  + 取消了function的变量提升性，这样函数的执行，只能在创建函数的代码之后，逻辑更加严谨；
  + 也防止了function所导致的一些“恶心”的问题，例如：块中的function可能会导致“函数的渣男性质”!!
*/
/* const fn = function (x, y) {
    let total = x + y;
    return function (z) {
        console.log(total + z);
    };
};
fn(10, 20)(30); */


/* let a = 0,
    b = 0;
let A = function (a) {
    A = function (b) {
        alert(a + b++);
    };
    alert(a++);
};
A(1);
A(2); */



/* 
下⾯代码是否可以，每隔1000MS依次输出 0 1 2 3 4  ? 
如果不可以，说明为啥？以及如何解决？ 
-------
不能实现需求，现在的效果是：每隔1秒输出的都是5！
因为：
  @1 var不会产生块级私有上下文，所以循环中的i是全局变量
  @2 每一轮循环设置一个定时器，此时定时器中设定的函数不会立即执行，需要等待多久后才会执行，但是循环会一直继续；因此定时器中的方法，都是在循环结束后「全局i=5」才执行的!
     第一轮 i=0 设置定时器(等待1秒) i++
     第二轮 i=1 设置定时器(等待2秒) i++
     ....
     第五轮 i=4 设置定时器(等待4秒) i++
     全局i=5，循环已经结束！！
  @3 每间隔1秒中，之前设置的定时器到达时间，执行之前设定的函数
    假设第一个定时器执行 EC(AN1)
      作用域链:<EC(AN1),EC(G)>
      形参赋值:- -
      代码执行：
        console.log(i); //i不是私有的，则找的是上级上下文(也就是全局)中的i，而全局的i此时已经是5
    ......

如何解决，让其实现效果？ -> 核心思路：闭包
真实项目中要合理使用闭包！！
*/

/* setTimeout(function (n) {
    // 定时器到时间，会把'珠峰'传递n「预先传递值」  -->  底层机制也是闭包
}, 1000, '珠峰'); */

for (var i = 0; i < 5; i++) {
    setTimeout(function (i) {
        console.log(i); //i是我们之前预先传递进来的值
    }, (i + 1) * 1000, i);
}

/* 
// 和下面代码原理一模一样：因为循环中出现let，那么每一轮循环，会自动创建一个私有的块级上下文（闭包），每一个私有上下文中都要有私有变量i，分别存储索引...
for (let i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, (i + 1) * 1000);
}  
*/


/* 
// 每一轮循环，都执行自执行函数，产生一个闭包「循环无论产生五个闭包」！而且把当前全局i的值赋值给闭包中的私有变量i...
//   第一轮 全局i=0  闭包1(私有i=0) i++
//   第二轮 全局i=1  闭包2(私有i=1) i++
//   ....
// 当定时器执行的时候，遇到的i不是小函数私有的，则找其上级上下文（对应的闭包）中的i，拿到的就是之前存储好的索引！！
for (var i = 0; i < 5; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i);
        }, (i + 1) * 1000);
    })(i);
} 
*/

/* for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, (i + 1) * 1000);
} */